<template>
  <div>
    <!-- 卡片 -->
    <div class="card-wrapper relative cursor-pointer shadow-lg transition-transform duration-300 hover:scale-105"
      :style="!isExpanded ? cardStyle : {}" ref="cardElement" @click="handleCardClick">
      <slot></slot>
    </div>

    <!-- 遮罩层 -->
    <div v-if="isExpanded" class="fixed inset-0 z-50 bg-black bg-opacity-50" @click.stop></div>

    <!-- 卡片放大过渡效果 -->
    <transition name="expand" @after-leave="resetCard">
      <div @click.stop v-if="isExpanded" class="card-overlay fixed rounded-2xl bg-[var(--inputBg)] shadow-lg overflow-hidden"
        :style="overlayStyles" ref="overlayElement">
        <div class="expanded-content items-center w-full h-full">
          <slot name="expanded"></slot>
        </div>
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive} from "vue";

  const cardElement = ref < HTMLElement | null > (null); // 初始卡片元素
  const overlayElement = ref < HTMLElement | null > (null); // 覆盖层元素
  const isExpanded = ref(false); // 卡片是否展开
  const overlayStyles = reactive < any > ({}); // 动态动画样式

  // 初始卡片的位置和大小
  let cardRect: DOMRect | null = null;

  // 打开卡片
  const handleCardClick = () => {
    if (!cardElement.value) return;
    
    // 获取卡片的位置和大小
    const rect = cardElement.value.getBoundingClientRect();
    cardRect = {
      top: rect.top,
      left: rect.left,
      width: rect.width,
      height: rect.height,
    };

    // 初始化覆盖层的样式为卡片的初始位置
    overlayStyles.position = "fixed";
    overlayStyles.top = `${cardRect.top}px`;
    overlayStyles.left = `${cardRect.left}px`;
    overlayStyles.width = `${cardRect.width}px`;
    overlayStyles.height = `${cardRect.height}px`;
    overlayStyles.zIndex = 999;
    overlayStyles.borderRadius = getComputedStyle(cardElement.value).borderRadius;

    // 展开卡片动画逻辑
    isExpanded.value = true;

    // 动态设置目标对话框的固定位置
    setTimeout(() => {
      overlayStyles.top = "50%"; // 固定在屏幕中间
      overlayStyles.left = "50%";
      overlayStyles.transform = "translate(-50%, -50%)"; // 居中
      overlayStyles.width = "50vw"; // 对话框宽度
      overlayStyles.height = "auto"; // 对话框高度
      overlayStyles.borderRadius = "1rem"; // 对话框圆角
    }, 600);
  };

  // 关闭卡片
  const closeCard = () => {
    if (!overlayElement.value || !cardRect) return;

    // 恢复卡片到原始位置和大小
    overlayStyles.top = `${cardRect.top}px`;
    overlayStyles.left = `${cardRect.left}px`;
    overlayStyles.transform = ""; // 清除 transform
    overlayStyles.width = `${cardRect.width}px`;
    overlayStyles.height = `${cardRect.height}px`;
    overlayStyles.borderRadius = getComputedStyle(cardElement.value).borderRadius;

    // 等待动画完成后隐藏覆盖层
    setTimeout(() => {
      isExpanded.value = false;
    }, 300); // 与 CSS 动画时间保持一致
  };

  // 重置卡片样式
  const resetCard = () => {
    overlayStyles.position = "";
    overlayStyles.top = "";
    overlayStyles.left = "";
    overlayStyles.transform = "";
    overlayStyles.width = "";
    overlayStyles.height = "";
    overlayStyles.borderRadius = "";
    overlayStyles.zIndex = "";
  };

  defineExpose({
    handleCardClick,
    closeCard,
  });
</script>

<style scoped>
  /* 放大过渡动画 */
  .expand-enter-active,
  .expand-leave-active {
    transition: all 0.3s ease;
  }

  .expand-enter-from,
  .expand-leave-to {
    transform: scale(0.9);
    opacity: 0;
  }

  /* 卡片内容样式 */
  .card-overlay {
    transition: all 0.3s ease;
    /* 过渡动画 */
  }

  .expand-leave-to {
    transform: scale(0.9);
    opacity: 0;
  }
</style>